﻿using Gma.System.MouseKeyHook;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace AutoLite.Revit.Tool;

/// <summary>
/// 钩子实现的模拟按下 revit“完成”的工具
/// </summary>
public class HookRevitFinish
{
    private static IKeyboardMouseEvents? events;

    /// <summary>
    /// 启动
    /// </summary>
    public static void Open()
    {
        if (events is null)
        {
            events = Hook.AppEvents();
            events.MouseDownExt += Events_MouseDownExt;//为什么MouseDownExt后还要MouseUpExt？
            events.MouseUpExt += Events_MouseUpExt; ;//别问，问就是有些奇怪bug。
        }
    }

    /// <summary>
    /// 关闭
    /// </summary>
    public static void Close()
    {
        if (events != null)
        {
            events.MouseDownExt -= Events_MouseDownExt;
            events.MouseUpExt -= Events_MouseUpExt;
            events.Dispose();
            events = null;
        }
    }

    private static void Events_MouseUpExt(object? sender, MouseEventExtArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            e.Handled = true;
        }
    }

    private static void Events_MouseDownExt(object? sender, MouseEventExtArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            Task.Run(Finish);
            e.Handled = true;
        }
    }

    /// <summary>
    /// 模拟按下“完成”按钮
    /// </summary>
    public static void Finish()
    {
        //这部分是激活revit界面的代码，无需理解，直接使用
        //IntPtr active = IntPtr.Zero;
        IntPtr rvtwindow = Autodesk.Windows.ComponentManager.ApplicationWindow;
        //active = rvtwindow;

        var list = new List<IntPtr>();
        var flag = EnumChildWindows(rvtwindow,
                   (hwnd, l) =>
                   {
                       StringBuilder windowText = new StringBuilder(200);
                       StringBuilder className = new StringBuilder(200);

                       GetWindowText(hwnd, windowText, windowText.Capacity);

                       GetClassName(hwnd, className, className.Capacity);

                       if ((windowText.ToString().Equals("完成", StringComparison.Ordinal) ||
                           windowText.ToString().Equals("Finish", StringComparison.Ordinal)) &&
                           className.ToString().Contains("Button"))
                       {
                           list.Add(hwnd);
                           return false;
                       }
                       return true;
                   }, IntPtr.Zero);

        var complete = list.FirstOrDefault();

        SendMessage(complete, 245, 0, 0);

        SetActiveWindow(rvtwindow);
    }

    private delegate bool CallBack(IntPtr hwnd, int lParam);

    [DllImport("user32.dll", CharSet = CharSet.None, ExactSpelling = false)]
    private static extern bool EnumChildWindows(IntPtr hwndParent, CallBack lpEnumFunc, IntPtr lParam);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpText, int nCount);

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

    [DllImport("user32.dll", EntryPoint = "SendMessageA")]
    private static extern int SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam);

    [DllImport("user32.dll")]
    private static extern IntPtr SetActiveWindow(IntPtr hwnd);
}